Skip to content

fix(zabbix): populate hostname on pulled and pushed alerts#6612

Open
washosk wants to merge 4 commits into
keephq:mainfrom
washosk:fix/zabbix-missing-hostname
Open

fix(zabbix): populate hostname on pulled and pushed alerts#6612
washosk wants to merge 4 commits into
keephq:mainfrom
washosk:fix/zabbix-missing-hostname

Conversation

@washosk

@washosk washosk commented Jul 3, 2026

Copy link
Copy Markdown

Fixes #6613

Summary

Zabbix alerts were missing the host name in two separate ways:

  • Polling (_get_alerts): the problem.get call never asked Zabbix for host data, so pulled alerts had no host information at all.
  • Webhook push (_format_alert): the installed Zabbix script sends the host as host_name / host_ip (matching the parameter names configured in setup_webhook), but the code read hostName / hostIp instead. The primary source, service ({HOST.HOST}), can be empty for problems tied to multiple hosts, and the fallback silently returned None due to this key mismatch.

Changes

  • _get_alerts: problem.get does not support selectHosts (verified against a live instance — it errors with Invalid parameter: unexpected parameter selectHosts). Fetch hosts via a separate batched event.get call on the same eventids and join them back in by eventid, mapping the host's visible name (falling back to its technical name) onto service/hostname on the AlertDto. Adds the event.get scope.
  • _format_alert: read host_name/host_ip (matching the actual webhook payload keys), falling back through hostName/hostIp and the older HOST.NAME/HOST.IP macro keys for backward compatibility with webhook installs set up before the mediatype→script migration (chore(provider): zabbix from mediatype to script #2397).

Note (added while re-testing against a live instance): also fixes an unrelated pre-existing bug in the same _get_alerts loop: problem.get never actually returns a status text field (that's a UI concept, not an API field), so STATUS_MAP.get(problem.pop("status", ""), AlertStatus.FIRING) always fell through to FIRING regardless of the problem's real state. Status is now derived from the acknowledged/suppressed flags problem.get does return, the same pattern already used by other providers (Datadog, PagerDuty, Grafana, ...) to report these states from a pull. problem.get only returns still-open problems, so resolved/ok remain unreachable here, same as before.

Test plan

  • Verified against a live production Zabbix instance: problem.get + event.get join now returns real hostnames for real open problems (confirmed several, e.g. host ke-mba-icolo02-fw01a for an OPNsense DHCP problem).
  • Verified suppressed/acknowledged flags on real problems now map to SUPPRESSED/ACKNOWLEDGED instead of always FIRING.
  • Verify pushed webhook alerts for a multi-host trigger problem now include a host name
  • No existing tests cover this provider; consider adding unit tests for _get_alerts and _format_alert covering these cases

Zabbix problem.get() alerts never carried a host, since _get_alerts()
never requested host data from the API. Add selectHosts to the request
and map it onto AlertDto's service/hostname fields.

The webhook push path had a separate bug: the installed script sends
the host as host_name/host_ip (matching its own parameter names), but
_format_alert() looked for hostName/hostIp, so the fallback silently
returned None whenever {HOST.HOST} was empty (e.g. multi-host trigger
problems).
@dosubot dosubot Bot added size:S This PR changes 10-29 lines, ignoring generated files. Bug Something isn't working Provider Providers related issues labels Jul 3, 2026
@CLAassistant

CLAassistant commented Jul 3, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@shahargl shahargl left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you just add the new fields and not remove the old one? For backward compatibility /older zabbix versions

talboren
talboren previously approved these changes Jul 5, 2026

@talboren talboren left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Jul 5, 2026
Per review: don't drop the hostName/hostIp lookups, add host_name/
host_ip alongside them. Also restore HOST.NAME/HOST.IP, the raw macro
keys used by the pre-script-based (mediatype) webhook installs that
predate keephq#2397 and may still be configured on older Zabbix instances.
@washosk

washosk commented Jul 10, 2026

Copy link
Copy Markdown
Author

Good catch pushed a fix that keeps hostName/hostIp (and the even older HOST.NAME/HOST.IP macro keys from the pre-script mediatype webhook) as fallbacks alongside host_name/host_ip, so older installs that haven't re-run the webhook setup keep working.

selectHosts is not a valid problem.get parameter -- Zabbix rejects it
with "Invalid parameter: unexpected parameter selectHosts", breaking
every poll (confirmed against a live production instance). Fetch
hosts via a separate batched event.get call on the same eventids and
join them back in by eventid instead. Requires the event.get scope.
@dosubot dosubot Bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:S This PR changes 10-29 lines, ignoring generated files. labels Jul 10, 2026
@washosk

washosk commented Jul 10, 2026

Copy link
Copy Markdown
Author

Correction to the earlier commit: problem.get does not support selectHosts (verified against a live instance — Zabbix rejects it with "Invalid parameter: unexpected parameter selectHosts", which broke every poll after deploying this branch). selectHosts is an event.get parameter, not problem.get.

Pushed a fix: _get_alerts now does a second batched event.get call on the fetched eventids (with selectHosts) and joins the hostname back in, instead of asking problem.get for something it doesn't support. This also adds the event.get scope requirement.

problem.get never returns a "status" text field, so the previous
STATUS_MAP.get(problem.pop("status", ""), ...) always fell through to
FIRING regardless of the problem's real state. Derive status from the
acknowledged/suppressed flags problem.get actually returns instead,
matching the pattern other providers (Datadog, PagerDuty, Grafana...)
already use to report these states from pull. problem.get only
returns open problems, so resolved/ok stay unreachable here (as
before).

Verified against real production problems: suppressed=1 now yields
SUPPRESSED, acknowledged=1 yields ACKNOWLEDGED, instead of both
showing as FIRING.
@washosk

washosk commented Jul 10, 2026

Copy link
Copy Markdown
Author

Note: rolled the status bug I mentioned above into this same PR instead of a separate issue, since it's the same _get_alerts loop.

problem.get never returns a "status" text field (that's a UI-only concept), so the old STATUS_MAP.get(problem.pop("status", ""), AlertStatus.FIRING) always fell through to FIRING no matter the real state. Now deriving status from the acknowledged/suppressed flags problem.get actually returns — same approach Datadog/PagerDuty/Grafana providers already use to report these states on pull. Verified against real production problems: a suppressed=1 problem now correctly comes back SUPPRESSED instead of FIRING.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something isn't working lgtm This PR has been approved by a maintainer Provider Providers related issues size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Zabbix alerts missing host name

4 participants